const canvas = document.getElementById('gameCanvas');
const ctx = canvas.getContext('2d');
const scoreDisplay = document.getElementById('score');
const messageDisplay = document.getElementById('message');
const restartButton = document.getElementById('restartButton');
const startButton = document.getElementById('startButton');

// Attach event listeners immediately after elements are defined
startButton.addEventListener('click', startCountdown);
restartButton.addEventListener('click', startGame);

const gridSize = 20;
let snake = [{ x: 10, y: 10 }];
let food = {};
let dx = 0;
let dy = 0;
let score = 0;
let changingDirection = false;
let gameInterval;
let gameRunning = false;
let countdownInterval;

function generateFood() {
    food = {
        x: Math.floor(Math.random() * (canvas.width / gridSize)),
        y: Math.floor(Math.random() * (canvas.height / gridSize))
    };
    snake.forEach(segment => {
        if (segment.x === food.x && segment.y === food.y) {
            generateFood();
        }
    });
}

function drawRect(x, y, color) {
    ctx.fillStyle = color;
    ctx.fillRect(x * gridSize, y * gridSize, gridSize, gridSize);
    ctx.strokeStyle = 'rgba(0, 0, 0, 0.2)'; /* Softer stroke */
    ctx.strokeRect(x * gridSize, y * gridSize, gridSize, gridSize);
}

function drawSnake() {
    snake.forEach((segment, index) => {
        let gradient;
        if (index === 0) { // Head
            gradient = ctx.createLinearGradient(segment.x * gridSize, segment.y * gridSize, (segment.x + 1) * gridSize, (segment.y + 1) * gridSize);
            gradient.addColorStop(0, '#61afef');
            gradient.addColorStop(1, '#56b6c2');
        } else { // Body
            gradient = ctx.createLinearGradient(segment.x * gridSize, segment.y * gridSize, (segment.x + 1) * gridSize, (segment.y + 1) * gridSize);
            gradient.addColorStop(0, '#56b6c2');
            gradient.addColorStop(1, '#61afef');
        }
        drawRect(segment.x, segment.y, gradient);
    });
}

function drawFood() {
    let gradient = ctx.createRadialGradient(
        food.x * gridSize + gridSize / 2, food.y * gridSize + gridSize / 2, 1,
        food.x * gridSize + gridSize / 2, food.y * gridSize + gridSize / 2, gridSize / 2
    );
    gradient.addColorStop(0, '#e5c07b');
    gradient.addColorStop(1, '#d19a66');
    drawRect(food.x, food.y, gradient);
}

function moveSnake() {
    if (!gameRunning) return;

    const head = { x: snake[0].x + dx, y: snake[0].y + dy };
    snake.unshift(head);
    changingDirection = false;

    const didEatFood = head.x === food.x && head.y === food.y;
    if (didEatFood) {
        score += 10;
        scoreDisplay.textContent = score;
        generateFood();
    } else {
        snake.pop();
    }
}

function checkCollision() {
    const head = snake[0];

    // Wall collision
    const hitLeftWall = head.x < 0;
    const hitRightWall = head.x >= canvas.width / gridSize;
    const hitTopWall = head.y < 0;
    const hitBottomWall = head.y >= canvas.height / gridSize;

    if (hitLeftWall || hitRightWall || hitTopWall || hitBottomWall) {
        return true;
    }

    // Self collision
    for (let i = 1; i < snake.length; i++) {
        if (head.x === snake[i].x && head.y === snake[i].y) {
            return true;
        }
    }
    return false;
}

function endGame() {
    gameRunning = false;
    clearInterval(gameInterval);
    messageDisplay.textContent = `Game Over! Your score: ${score}`;
    messageDisplay.classList.remove('hidden');
    restartButton.textContent = 'Play Again';
    restartButton.classList.remove('hidden');
    startButton.classList.add('hidden'); // Ensure start button is hidden
}

function gameLoop() {
    if (checkCollision()) {
        endGame();
        return;
    }
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    drawFood();
    moveSnake();
    drawSnake();
}

function startGame() {
    snake = [{ x: 10, y: 10 }];
    food = {};
    dx = 1; // Initial direction right
    dy = 0;
    score = 0;
    scoreDisplay.textContent = score;
    messageDisplay.classList.add('hidden'); // Hide message after game starts
    restartButton.classList.add('hidden');
    startButton.classList.add('hidden'); // Hide start button when game begins
    generateFood();
    gameRunning = true;
    if (gameInterval) clearInterval(gameInterval);
    gameInterval = setInterval(gameLoop, 150); // Game speed
}

function startCountdown() {
    let count = 3;
    messageDisplay.classList.remove('hidden'); // Show message
    startButton.classList.add('hidden'); // Hide start button
    restartButton.classList.add('hidden'); // Ensure restart button is hidden during countdown

    messageDisplay.textContent = `Game starting in ${count}... Use Arrow Keys to move!`;
    countdownInterval = setInterval(() => {
        count--;
        if (count > 0) {
            messageDisplay.textContent = `Game starting in ${count}... Use Arrow Keys to move!`;
        } else {
            clearInterval(countdownInterval);
            startGame();
        }
    }, 1000);
}


function changeDirection(event) {
    if (!gameRunning && !countdownInterval) { // If game is not running and no countdown is active
        // Trigger game start/countdown with any arrow key press
        startCountdown();
        return; // Prevent immediate snake movement after starting
    }

    if (changingDirection) return;
    changingDirection = true;

    const keyPressed = event.keyCode;
    const LEFT_KEY = 37;
    const RIGHT_KEY = 39;
    const UP_KEY = 38;
    const DOWN_KEY = 40;

    const goingUp = dy === -1;
    const goingDown = dy === 1;
    const goingRight = dx === 1;
    const goingLeft = dx === -1;

    if (keyPressed === LEFT_KEY && !goingRight) {
        dx = -1;
        dy = 0;
    } else if (keyPressed === UP_KEY && !goingDown) {
        dx = 0;
        dy = -1;
    } else if (keyPressed === RIGHT_KEY && !goingLeft) {
        dx = 1;
        dy = 0;
    } else if (keyPressed === DOWN_KEY && !goingUp) {
        dx = 0;
        dy = 1;
    }
}

function handleMouseClick(event) {
    if (changingDirection || !gameRunning) return;
    changingDirection = true;

    const rect = canvas.getBoundingClientRect();
    const clickX = event.clientX - rect.left;
    const clickY = event.clientY - rect.top;

    const head = snake[0];
    const headCenterX = (head.x * gridSize) + (gridSize / 2);
    const headCenterY = (head.y * gridSize) + (gridSize / 2);

    const goingUp = dy === -1;
    const goingDown = dy === 1;
    const goingRight = dx === 1;
    const goingLeft = dx === -1;

    // Determine direction based on click relative to snake head
    if (Math.abs(clickX - headCenterX) > Math.abs(clickY - headCenterY)) {
        // Horizontal click
        if (clickX > headCenterX && !goingLeft) { // Clicked right
            dx = 1;
            dy = 0;
        } else if (clickX < headCenterX && !goingRight) { // Clicked left
            dx = -1;
            dy = 0;
        }
    } else {
        // Vertical click
        if (clickY > headCenterY && !goingUp) { // Clicked down
            dx = 0;
            dy = 1;
        } else if (clickY < headCenterY && !goingDown) { // Clicked up
            dx = 0;
            dy = -1;
        }
    }
}

document.addEventListener('keydown', changeDirection);
canvas.addEventListener('click', handleMouseClick);


document.addEventListener('DOMContentLoaded', () => {
    // Initial display: canvas and score are visible, message and start button are shown
    messageDisplay.textContent = 'Click Start to Play!'; // Set initial message
    messageDisplay.classList.remove('hidden'); // Ensure message is visible
    startButton.classList.remove('hidden'); // Ensure start button is visible
    restartButton.classList.add('hidden'); // Ensure restart button is hidden initially

    // Start button styling
    startButton.classList.add('start-button'); // Add the class for styling

    // Load Google Fonts for "Press Start 2P"
    const link = document.createElement('link');
    link.href = 'https://fonts.googleapis.com/css2?family=Press+Start+2P&display=swap';
    link.rel = 'stylesheet';
    document.head.appendChild(link);
});
